package com.c.util;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;

import cn.hutool.json.JSONObject;

public class RedisUtils {

	private StringRedisTemplate stringRedisTemplate;

	public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
		this.stringRedisTemplate = stringRedisTemplate;
	}

	/**
	 * 删除缓存<br>
	 * 根据key精确匹配删除
	 * 
	 * @param key
	 */
	public void del(String... key) {
		if (key != null && key.length > 0) {
			if (key.length == 1) {
				stringRedisTemplate.delete(key[0]);
			} else {
				stringRedisTemplate.delete(CollectionUtils.arrayToList(key));
			}
		}
	}

	/**
	 * 放入redis，更新也使用这个方法，前提key要存在
	 * 
	 * @param hashName
	 * @param key
	 * @param value
	 */
	public void setHash(String hashName, Object key, Object value) {
		stringRedisTemplate.opsForHash().put(hashName, key, value);
	}

	public Object getHash(String hashName, Object key) {
		return stringRedisTemplate.opsForHash().get(hashName, key);
	}

	/**
	 * 取得缓存（int型）
	 * 
	 * @param key
	 * @return
	 */
	public Integer getInt(String key) {
		String value = stringRedisTemplate.boundValueOps(key).get();
		if (StringUtils.isNotBlank(value)) {
			return Integer.valueOf(value);
		}
		return null;
	}

	/**
	 * 取得缓存（字符串类型）
	 * 
	 * @param key
	 * @return
	 */
	public String getStr(String key) {
		return stringRedisTemplate.boundValueOps(key).get();
	}

	/**
	 * 取得缓存（字符串类型）
	 * 
	 * @param key
	 * @return
	 */
	public String getStr(String key, boolean retain) {
		String value = stringRedisTemplate.boundValueOps(key).get();
		if (!retain) {
			stringRedisTemplate.delete(key);
		}
		return value;
	}

	/**
	 * 获取缓存<br>
	 * 注：基本数据类型(Character除外)，请直接使用get(String key, Class<T> clazz)取值
	 * 
	 * @param key
	 * @return
	 */
	public Object getObj(String key) {
		return stringRedisTemplate.boundValueOps(key).get();
	}

	/**
	 * 获取缓存<br>
	 * 注：java 8种基本类型的数据请直接使用get(String key, Class<T> clazz)取值
	 * 
	 * @param key
	 * @param retain
	 *            是否保留
	 * @return
	 */
	public Object getObj(String key, boolean retain) {
		Object obj = stringRedisTemplate.boundValueOps(key).get();
		if (!retain) {
			stringRedisTemplate.delete(key);
		}
		return obj;
	}

	/**
	 * 将基本类型的封装对象写入缓存
	 * 
	 * @param key
	 * @param value
	 * @param time
	 *            失效时间(秒)
	 */
	public void set(String key, Object value, Long time) {
		if (value.getClass().equals(String.class)) {
			stringRedisTemplate.opsForValue().set(key, value.toString());
		} else if (value.getClass().equals(Integer.class)) {
			stringRedisTemplate.opsForValue().set(key, value.toString());
		} else if (value.getClass().equals(Double.class)) {
			stringRedisTemplate.opsForValue().set(key, value.toString());
		} else if (value.getClass().equals(Float.class)) {
			stringRedisTemplate.opsForValue().set(key, value.toString());
		} else if (value.getClass().equals(Short.class)) {
			stringRedisTemplate.opsForValue().set(key, value.toString());
		} else if (value.getClass().equals(Long.class)) {
			stringRedisTemplate.opsForValue().set(key, value.toString());
		} else if (value.getClass().equals(Boolean.class)) {
			stringRedisTemplate.opsForValue().set(key, value.toString());
		} else {
			stringRedisTemplate.opsForValue().set(key, JsonMapper.toJsonString(value));
		}
		if (time > 0) {
			stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
		}
	}

	/**
	 * 将value对象以JSON格式写入缓存
	 * 
	 * @param key
	 * @param value
	 * @param time
	 *            失效时间(秒)
	 */
	public void setJson(String key, Object value, Long time) {
		stringRedisTemplate.opsForValue().set(key, JsonMapper.toJsonString(value));
		if (time > 0) {
			stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
		}
	}

	/**
	 * 更新key对象field的值
	 * 
	 * @param key
	 *            缓存key
	 * @param field
	 *            缓存对象field
	 * @param value
	 *            缓存对象field值
	 */
	public void setJsonField(String key, String field, String value) {
		JSONObject obj = JsonMapper.fromJsonString(stringRedisTemplate.boundValueOps(key).get(), JSONObject.class);
		obj.put(field, value);
		stringRedisTemplate.opsForValue().set(key, obj.toJSONString(0));
	}

	/**
	 * 将map写入缓存
	 * 
	 * @param key
	 * @param map
	 * @param time
	 *            失效时间(秒)
	 */
	public <T> void setMap(String key, Map<String, T> map) {
		stringRedisTemplate.opsForHash().putAll(key, map);
	}

	/**
	 * 获取map缓存
	 * 
	 * @param key
	 * @param clazz
	 * @return
	 */
	public Map<String, T> mget(String key, Class<T> clazz) {
		BoundHashOperations<String, String, T> boundHashOperations = stringRedisTemplate.boundHashOps(key);
		return boundHashOperations.entries();
	}

	/**
	 * 获取map缓存中的某个对象
	 * 
	 * @param key
	 * @param field
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T getMapField(String key, String field, Class<T> clazz) {
		return (T) stringRedisTemplate.boundHashOps(key).get(field);
	}

	/**
	 * 指定缓存的失效时间
	 * 
	 * @author FangJun
	 * @date 2016年8月14日
	 * @param key
	 *            缓存KEY
	 * @param time
	 *            失效时间(秒)
	 */
	public void expire(String key, int time) {
		if (time > 0) {
			stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
		}
	}

	/**
	 * 添加set
	 * 
	 * @param key
	 * @param value
	 */
	public void sadd(String key, String... value) {
		stringRedisTemplate.boundSetOps(key).add(value);
	}

	/**
	 * 模糊查询keys
	 * 
	 * @param pattern
	 * @return
	 */
	public Set<String> keys(String pattern) {
		return stringRedisTemplate.keys(pattern);
	}
}
